//
//  Model3D.hpp
//  C3W_Demo_By_Fan
//
//  Created by 范静涛 on 2024/7/23.
//

//------------------------------------------------------------------------------
//【文件名】Model3D.hpp
//【功能模块和目的】三维模型类声明
//【开发者及日期】范静涛 2024/7/23
//【更改记录】2024/8/12 范静涛 修正了部分成员函数形参缩写为完成单词
//------------------------------------------------------------------------------

#ifndef Model3D_hpp
#define Model3D_hpp

//Face3D类所属头文件
#include "Face3D.hpp"
//Line3D类所属头文件
#include "Line3D.hpp"
//Point3D类所属头文件
#include "Point3D.hpp"
//std::vector所属头文件
#include <vector>
//size_t所属头文件
#include <cstddef>
//std::shared_ptr类所属头文件
#include <memory>
//StringList类所属头文件
#include "StringList.hpp"

//------------------------------------------------------------------------------
//【类名】Model3D
//【功能】三维模型类
//【接口说明】
//    带参数构造函数
//    拷贝构造函数
//    赋值运算符overload
//    虚析构函数（可能做基类）
//    以多种参数形式添加一个Face3D
//    以多种参数形式删除一个Face3D
//    以多种参数形式修改一个Face3D
//    删除所有Face3D
//    以多种参数形式添加一个Line3D
//    以多种参数形式删除一个Line3D
//    以多种参数形式修改一个Line3D
//    删除所有Line3D
//    删除所有Face3D和Line3D
//    以多种参数形式模型合并，自赋值运算符overload
//    以多种参数形式部分移除模型，自赋值运算符overload
//    以多种参数形式模型合并，运算符overload
//    以多种参数形式部分移除模型，运算符overload
//【开发者及日期】 范静涛 2024/7/23
//【更改记录】2024/8/12 范静涛 修正了部分成员函数形参缩写为完成单词
//------------------------------------------------------------------------------
class Model3D{
public:
    //--------------------------------------------------------------------------
    //必要的构造、析构、赋值行为
    //--------------------------------------------------------------------------
    //默认构造函数
    Model3D();
    //带参构造函数
    Model3D
        (const std::vector<Face3D>& vFaces, const std::vector<Line3D>& vLines);
    //拷贝构造函数
    Model3D(const Model3D& Source);
    //赋值运算符overload
    Model3D& operator=(const Model3D& Source);
    //虚析构函数（可能做基类），无动态构造成员，默认实现
    virtual ~Model3D() = default;
    //--------------------------------------------------------------------------
    //非静态Setter成员函数
    //--------------------------------------------------------------------------
    //添加一个Face3D
    bool AppendFace(const Face3D& AFace);
    //添加一个Face3D
    bool AppendFace
         (const Point3D& Point1, const Point3D& Point2, const Point3D& Point3);
    //删除一个Face3D
    bool RemoveFace(const Face3D& AFace);
    //删除一个Face3D
    bool RemoveFace
        (const Point3D& Point1, const Point3D& Point2, const Point3D& Point3);
    //修改一个Face3D
    bool ModifyFace(const Face3D& From,  const Face3D& To);
    //修改一个Face3D
    bool ModifyFace
         (const Face3D& AFace, const Point3D& From, const Point3D& To);
    //修改一个Face3D
    bool ModifyFace(const Face3D& AFace, size_t Index, const Point3D& To);
    //删除所有Face3D
    void ClearFaces();
    //添加一个Line3D
    bool AppendLine(const Line3D& ALine);
    //添加一个Line3D
    bool AppendLine(const Point3D& Point1, const Point3D& Point2);
    //删除一个Line3D
    bool RemoveLine(const Line3D& ALine);
    //删除一个Line3D
    bool RemoveLine(const Point3D& Point1, const Point3D& Point2);
    //修改一个Line3D
    bool ModifyLine(const Line3D& From,  const Line3D& To);
    //修改一个Line3D
    bool ModifyLine
         (const Line3D& ALine, const Point3D& From, const Point3D& To);
    //修改一个Line3D
    bool ModifyLine(const Line3D& ALine, size_t Index, const Point3D& To);
    //删除所有Line3D
    void ClearLines();
    //删除所有Face3D和Line3D
    void Clear();
    //模型合并，赋值运算符overload
    Model3D& operator+=(const Model3D& AModel);
    //模型合并Face3D，自赋值运算符overload
    Model3D& operator+=(const std::vector<Face3D>& Faces);
    //模型合并Line3D，自赋值运算符overload
    Model3D& operator+=(const std::vector<Line3D>& Lines);
    //模型移除，自赋值运算符overload
    Model3D& operator-=(const Model3D& AModel);
    //模型移除Face3D，自赋值运算符overload
    Model3D& operator-=(const std::vector<Face3D>& Faces);
    //模型移除Line3D，自赋值运算符overload
    Model3D& operator-=(const std::vector<Line3D>& Lines);
    //--------------------------------------------------------------------------
    //非静态Getter成员函数：需检查所有Getter是否有后置const
    //--------------------------------------------------------------------------
    //模型合并，运算符overload
    Model3D operator+(const Model3D& AModel) const;
    //模型合并Face3D，运算符overload
    Model3D operator+(const std::vector<Face3D>& Faces) const;
    //模型合并Line3D，运算符overload
    Model3D operator+(const std::vector<Line3D>& Lines) const;
    //模型移除，运算符overload
    Model3D operator-(const Model3D& AModel) const;
    //模型移除Face3D，运算符overload
    Model3D operator-(const std::vector<Face3D>& Faces) const;
    //模型移除Line3D，运算符overload
    Model3D operator-(const std::vector<Line3D>& Lines) const;
    //--------------------------------------------------------------------------
    //非静态Setter/Getter共用成员
    //--------------------------------------------------------------------------
    //模型名
    std::string Name{std::string{"NO NAME"}};
    //模型注释
    StringList Comments;
private:
    //--------------------------------------------------------------------------
    //私有 非静态Setter成员函数
    //--------------------------------------------------------------------------
    //指定Face3D迭代器搜索
    std::vector<std::shared_ptr<Face3D>>::iterator FindFaceIter
         (const Face3D& AFace);
    //指定Line3D迭代器搜索
    std::vector<std::shared_ptr<Line3D>>::iterator FindLineIter
         (const Line3D& ALine);
    //计算更新包围盒
    void CalcBoundBox();

    //--------------------------------------------------------------------------
    //私有 数据成员
    //--------------------------------------------------------------------------
    //Face3D总数
    size_t  m_FaceCount{0};
    //Line3D总数
    size_t  m_LineCount{0};
    //Point3D总数(不同Face3D和Line3D中的Point3D重复计数)
    size_t  m_PointCount{0};
    //Element3D总数（Facd3D + Line3D）
    size_t  m_ElementCount{0};
    //Face3D总面积
    double  m_Area{0};
    //Line3D总长度
    double  m_Length{0};
    //包围盒X边长度
    double  m_BoundBox_X{0};
    //包围盒Y边长度
    double  m_BoundBox_Y{0};
    //包围盒Z边长度
    double  m_BoundBox_Z{0};
    //包围盒体积
    double  m_BoundBox_Vol{0};
    //Face3D对象指针列表
    std::vector<std::shared_ptr<Face3D>> m_Faces{};
    //Line3D对象指针列表
    std::vector<std::shared_ptr<Line3D>> m_Lines{};
public:
    //--------------------------------------------------------------------------
    //非静态Getter成员：常引用
    //--------------------------------------------------------------------------
    //Face3D总数
    const size_t& FaceCount{m_FaceCount};
    //Line3D总数
    const size_t& LineCount{m_LineCount};
    //Point3D总数(不同Face3D和Line3D中的Point3D重复计数)
    const size_t& PointCount{m_PointCount};
    //Element3D总数（Facd3D + Line3D）
    const size_t& ElementCount{m_ElementCount};
    //Face3D总面积
    const double& Area{m_Area};
    //Line3D总长度
    const double& Length{m_Length};
    //包围盒X边长度
    const double& BoundBox_X{m_BoundBox_X};
    //包围盒Y边长度
    const double& BoundBox_Y{m_BoundBox_Y};
    //包围盒Z边长度
    const double& BoundBox_Z{m_BoundBox_Z};
    //包围盒体积
    const double& BoundBox_Vol{m_BoundBox_Vol};
    //Face3D对象指针列表
    const std::vector<std::shared_ptr<Face3D>>& Faces{m_Faces};
    //Line3D对象指针列表
    const std::vector<std::shared_ptr<Line3D>>& Lines{m_Lines};

};
#endif /* Model3D_hpp */
